package org.wisdom.data.jpa.support.events;

import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PreUpdateEvent;
import org.hibernate.event.spi.PreUpdateEventListener;
import org.hibernate.internal.SessionFactoryImpl;
import org.springframework.stereotype.Component;
import org.wisdom.data.jpa.entity.WisdomEntity;
import org.wisdom.exception.BusinessException;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManagerFactory;

/**
 * 验证时间戳有效性
 *
 * @author 张智研
 * @date 2022/05/22 14:15
 */
@Component
public class WisdomPreUpdateEvent implements PreUpdateEventListener {

    private final transient EntityManagerFactory entityManagerFactory;

    public WisdomPreUpdateEvent(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    @PostConstruct
    private void init() {
        SessionFactoryImpl sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl.class);
        EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
        registry.getEventListenerGroup(EventType.PRE_UPDATE).appendListener(this);
    }

    @Override
    public boolean onPreUpdate(PreUpdateEvent preUpdateEvent) {
        if (preUpdateEvent.getEntity() instanceof WisdomEntity) {
            String[] names = preUpdateEvent.getPersister().getPropertyNames();
            for (int i = 0; i < names.length; i++) {
                if ("timeStamp".equals(names[i])) {
                    Object oldTimeStamp = preUpdateEvent.getOldState()[i];
                    Object timeStamp = preUpdateEvent.getState()[i];
//                    if(timeStamp == null) {
//                        throw new BusinessException(100100, "数据时间戳丢失，请重新获取最新数据进行修改！");
//                    }else if (oldTimeStamp != null && ((Long)oldTimeStamp > (Long)timeStamp)) {
//                        throw new BusinessException(100101, "数据已被修改,请重新获取最新数据进行修改！");
//                    }
                    if (timeStamp != null && oldTimeStamp != null && ((Long)oldTimeStamp > (Long)timeStamp)) {
                        throw new BusinessException(100101, "数据已被修改,请重新获取最新数据进行修改！");
                    }
                    preUpdateEvent.getState()[i] = System.currentTimeMillis();
                } else if (null == preUpdateEvent.getState()[i]) {
                    preUpdateEvent.getState()[i] = preUpdateEvent.getOldState()[i];
                }
            }
        }
        return false;
    }
}
